home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-01 / smailsrc.zip / UUPC.ZIP / DCP.C < prev    next >
Text File  |  1990-04-04  |  9KB  |  444 lines

  1. /*
  2.     For    best results in    visual layout while viewing this file, set
  3.     tab    stops to every 8 columns.
  4. */
  5.  
  6. /*
  7.     dcp.c
  8.  
  9.     Revised edition of dcp
  10.  
  11.     Stuart Lynne May/87
  12.  
  13.     Copyright (c) Richard H. Lamb 1985,    1986, 1987
  14.     Changes Copyright (c) Stuart Lynne 1987
  15.  
  16.     Maintenance    Notes:
  17.  
  18.     25Aug87 - Added a version number - Jal
  19.     25Aug87 - Return 0 if contact made with host, or 5 otherwise.
  20.     04Sep87 - Bug causing premature sysend() fixed. - Randall Jessup.
  21. */
  22.  
  23. /* "DCP" a uucp    clone. Copyright Richard H. Lamb 1985,1986,1987    */
  24.  
  25. /*
  26.     This program implements a uucico type file transfer    and remote
  27.     execution protocol.
  28.  
  29.     Usage:  uuio [-s sys] [-r] [-x debug]
  30.  
  31.     e.g.
  32.  
  33.     uuio [-x n] -r          slave mode, wait for an incoming call.
  34.     uuio [-x n]    -s HOST        call the host "HOST".
  35.     uuio [-x n]    -s all        call all known hosts in the    systems    file.
  36.     uuio [-x n]    -s any        call any host we have work queued for.
  37.     uuio [-x n]             same as the above.
  38. */
  39.  
  40. /*
  41.  *  Modified 4/4/90 by Stephen Trier
  42.  *  Now Supports smail/PC
  43.  *
  44.  *  Removed internal rmail; added support for external rnews.
  45.  *  Made -r flag a boolean, no argument required.
  46.  */
  47.  
  48. #include "dcp.h"
  49.  
  50. #include "getopt.h"
  51.  
  52. #define VERSION "UUPC/uuio version 1.06"
  53.  
  54. int pktsize;                /* packet size for this protocol*/
  55. int remote;                 /* -1 means we're remote    */
  56. int msgtime;                /* timout setting (length)  */
  57. int fp;                     /* current disk file handle */
  58. FILE *fwork, *fsys, *syslog;
  59. char workfile[80];          /* name of current workfile */
  60. char *Rmtname =    nil(char);  /* system we want to call    */
  61. char rmtname[20];           /* system we end up talking to  */
  62. char s_systems[64];         /* full-name of systems file    */
  63.  
  64. static char master(), slave(), receive(), send();
  65. static int dcxqt();
  66.  
  67.  
  68. static void cant(file)
  69. char *file;
  70. {
  71.  
  72.     fprintf(stderr, "Can't open: \"%s\"\n", file);
  73.  
  74.     exit(8);
  75.  
  76. } /*cant*/
  77.  
  78.  
  79. int dcpmain(argc, argv)
  80. int argc;
  81. char *argv[];
  82. {
  83.     int    Contacted = FALSE;
  84.     int    option;
  85.  
  86.     debuglevel = 0;
  87.     remote = MASTER;
  88.     fp = -1;
  89.     fwork = nil(FILE);
  90.  
  91.     while ((option = getopt(argc, argv,    "rs:x:")) != EOF)
  92.     switch (option) {
  93.         case 'r':
  94.         remote = !remote;
  95.         break;
  96.         case 's':
  97.         Rmtname = strdup(optarg);
  98.         break;
  99.         case 'x':
  100.         debuglevel = atoi(optarg);
  101.         break;
  102.         case '?':
  103.         puts("\nUsage:\tuuio [-s sys] [-r] [-x debug]");
  104.         return 4;
  105.         }
  106.     if (optind != argc)    {
  107.     puts("Extra parameter(s) at end.");
  108.     return 4;
  109.     }
  110.  
  111.     if (Rmtname    == nil(char))
  112.     Rmtname = "any";
  113.  
  114.     if ((logfile = FOPEN(LOGFILE, "a", TEXT)) == nil(FILE))
  115.     cant(LOGFILE);
  116.     logecho = ((remote == MASTER) ? TRUE : FALSE);
  117.  
  118.     /*
  119.     if ((syslog = FOPEN(SYSLOG, "a", TEXT)) == nil(FILE))
  120.     cant(SYSLOG);
  121.     */
  122.  
  123.     mkfilename(s_systems, confdir, SYSTEMS);
  124.  
  125.     printmsg(0,    "%s", VERSION);
  126.  
  127.     if (remote == MASTER) {
  128.  
  129.     char m_state = 'I';
  130.  
  131.     printmsg(0, "calling \"%s\", debug=%d",
  132.         Rmtname, debuglevel);
  133.  
  134.     if ((fsys = FOPEN(s_systems, "r", TEXT)) == nil(FILE))
  135.         exit(FAILED);
  136.  
  137.     for ( ; ; ) {
  138.         printmsg(4, "M state = %c", m_state);
  139.         switch (m_state) {
  140.         case 'I':
  141.             m_state = getsystem();
  142.             break;
  143.         case 'S':
  144.             m_state = callup();
  145.             break;
  146.         case 'P':
  147.             m_state = startup();
  148.             break;
  149.         case 'D':
  150.             m_state = master();
  151.             Contacted = TRUE;
  152.             break;
  153.         case 'Y':
  154.             m_state = sysend();
  155.             break;
  156.         case 'G':
  157.             if (equal(Rmtname, "any"))
  158.             m_state = 'Y';
  159.             else
  160.             m_state = 'I';
  161.             break;
  162.         }
  163.         if (m_state == 'A')
  164.         break;
  165.     }
  166.     fclose(fsys);
  167.  
  168.     }
  169.     else {    /* slave mode */
  170.  
  171.     char s_state = 'L';
  172.  
  173.     if (openline(E_indevice, E_inspeed) == -1) {
  174.         printmsg(0, "can't open serial port");
  175.         return FALSE;
  176.     }
  177.  
  178.     for ( ; ; ) {
  179.         printmsg(4, "S state = %c", s_state);
  180.         switch (s_state) {
  181.         case 'L':
  182.             s_state = login();
  183.             break;
  184.         case 'I':
  185.             s_state = startup();
  186.             break;
  187.         case 'R':
  188.             s_state = slave();
  189.             break;
  190.         case 'Y':
  191.             s_state = sysend();
  192.             break;
  193.         }
  194.         if (s_state == 'A')
  195.         break;
  196.         }
  197.     closeline();
  198.  
  199.     }
  200.  
  201.     /* scan and    process    any recieved X.* files */
  202.     printmsg(2,    "calling dcxqt...");
  203.     if (dcxqt())
  204.     printmsg(0, "Error during dcxqt()!");
  205.  
  206.     if (!Contacted)
  207.     printmsg(0, "\nCould not connect to remote system.");
  208.  
  209.     fclose(logfile);
  210.     /*
  211.     fclose(syslog);
  212.     */
  213.  
  214.     return Contacted ? 0 : 5;
  215.  
  216. } /*dcpmain*/
  217.  
  218.  
  219. /*
  220.     m a    s t e r
  221. */
  222.  
  223. static char master()
  224. {
  225.     char master_state =    'I';
  226.  
  227.     for    ( ; ; )    {
  228.     printmsg(4, "top level MASTER mode state = %c", master_state);
  229.     switch (master_state) {
  230.         case 'I':
  231.         master_state = sinit();
  232.         break;
  233.         case 'B':
  234.         master_state = scandir(rmtname);
  235.         break;
  236.         case 'S':
  237.         master_state = send();
  238.         break;
  239.         case 'Q':
  240.         master_state = sbreak();
  241.         break;
  242.         case 'G':
  243.         master_state = receive();
  244.         break;
  245.         case 'C':
  246.         master_state = 'Y';
  247.         break;
  248.         case 'Y':
  249.         master_state = endp();
  250.         break;
  251.         case 'P':
  252.         return 'Y';
  253.         case 'A':
  254.         return 'A';
  255.         default:
  256.         return 'A';
  257.         }
  258.     }
  259.  
  260. } /*master*/
  261.  
  262.  
  263. /*
  264.     s l    a v e
  265. */
  266.  
  267. static char slave()
  268. {
  269.     char slave_state = 'I';
  270.  
  271.     for    ( ; ; )    {
  272.     printmsg(4, "top level SLAVE mode state = %c", slave_state);
  273.     switch (slave_state) {
  274.         case 'I':
  275.         slave_state = rinit();
  276.         break;
  277.         case 'F':
  278.         slave_state = receive();
  279.         break;
  280.         case 'C':
  281.         slave_state = schkdir();
  282.         break;
  283.         case 'T':
  284.         slave_state = 'B';
  285.         break;
  286.         case 'B':
  287.         slave_state = scandir(rmtname);
  288.         break;
  289.         case 'S':
  290.         slave_state = send();
  291.         break;
  292.         case 'Q':
  293.         slave_state = sbreak();
  294.         break;
  295.         case 'G':
  296.         return 'Y';
  297.         case 'Y':
  298.         slave_state = endp();
  299.         break;
  300.         case 'P':
  301.         return 'Y';
  302.         case 'A':
  303.         return 'A';
  304.         default:
  305.         return 'A';
  306.         }
  307.     }
  308.  
  309. } /*slave*/
  310.  
  311.  
  312. /*
  313.     r e    c e i v    e
  314.  
  315.     This is the    state table switcher for receiving files.
  316. */
  317.  
  318. static char receive()
  319. {
  320.     char receive_state = 'F';    /* Receive-Init    is the start state */
  321.  
  322.     for    ( ; ; )    {   /* Do until    done */
  323.     printmsg(4, "receive state: %c", receive_state);
  324.     switch (receive_state) {
  325.         case 'F':   /* Receive-File     */
  326.         receive_state = rfile();
  327.         break;
  328.         case 'D':   /* Receive-Data     */
  329.         receive_state = rdata();
  330.         break;
  331.         case 'C':   /* Complete state   */
  332.         return 'C';
  333.         case 'A':   /* "Abort" state    */
  334.         return 'Y';
  335.         default:
  336.         return 'Y';
  337.         }
  338.     }
  339.  
  340. } /*receive*/
  341.  
  342.  
  343. /*
  344.     s e    n d
  345.  
  346.     State table    switcher for sending files
  347.  
  348.     Loops until    either it finishes, or an error    is encountered.
  349.     Routines called by send() are responsible for changing the state.
  350. */
  351.  
  352. static char send()
  353. {
  354.     char send_state = 'F';  /* Send initiate is    the start state    */
  355.  
  356.     fp = -1;    /* reset file getter/opener */
  357.  
  358.     for    ( ; ; )    {   /* Do this as long as necessary */
  359.     printmsg(4, "send state: %c", send_state);
  360.     switch (send_state) {
  361.         case 'F':
  362.         send_state = sfile();
  363.         break;  /* Send-File */
  364.         case 'D':
  365.         send_state = sdata();
  366.         break;  /* Send-Data */
  367.         case 'Z':
  368.         send_state = seof();
  369.         break;  /* Send-End-of-File */
  370.         case 'B':
  371.         return 'B'; /* Complete */
  372.         case 'A':
  373.         return 'Y'; /* "Abort" */
  374.         default:
  375.         return 'Y'; /* Unknown, fail */
  376.         }
  377.     }
  378.  
  379. } /*send*/
  380.  
  381.  
  382. /*
  383.     d c    x q t
  384.  
  385.     A command formatter    for DCP.  RH Lamb
  386.  
  387.     Sets up stdin and stdout on    various    machines.
  388.     There is NO    command    checking so watch what you send    and who    you let
  389.     to have access to your machine.  "C    rm /usr/*.*" could be executed!
  390. */
  391.  
  392. static int dcxqt()
  393. {
  394.     char xfile[80];
  395.  
  396.     while (xscandir(xfile) != nil(char)) {
  397.     char command[60], input[60], output[60], line[BUFSIZ];
  398.     char hostfile[132];
  399.     FILE *fxqt;
  400.  
  401.     fxqt = FOPEN(xfile,    "r", BINARY);    /* inbound X.* file */
  402.     printmsg(2,    "dcxqt:    processing %s",    xfile);
  403.     input[0] = output[0] = command[0] =    '\0';
  404.     while (fgets(line, BUFSIZ, fxqt) !=    nil(char)) {
  405.     char *cp;
  406.  
  407.     if ((cp    = strchr(line, '\n')) != nil(char))
  408.         *cp = '\0';
  409.  
  410.     printmsg(8, "dcxqt: %s", line);
  411.     switch (line[0]) {
  412.         case 'U':
  413.         break;
  414.         case 'I':
  415.         strcpy(input, &line[2]);
  416.         break;
  417.         case 'O':
  418.         strcpy(output, &line[2]);
  419.         break;
  420.         case 'C':
  421.         strcpy(command, &line[2]);
  422.         break;
  423.         case 'R':
  424.         break;
  425.         default :
  426.         break;
  427.         }
  428.     }
  429.     fclose(fxqt);
  430.  
  431.     printmsg(0,    "xqt: %s", command);
  432.     shell(command, input, output, nil(char));
  433.  
  434.     unlink(xfile);  /* already local name */
  435.     importpath(hostfile, input);
  436.     unlink(hostfile);
  437.     importpath(hostfile, output);
  438.     unlink(hostfile);
  439.     }
  440.  
  441.     return FALSE;
  442.  
  443. } /*dcxqt*/
  444.